<!--
 * @description 瀑布流组件
 * @author: 陈陈
 * @date: 2025/05/09
 * @phone: 18560000860
 * @email: 18560000860@qq.com
 * @company: 济南晨霜信息技术有限公司 /
 * @business: 承接前后端项目的开发
-->
<template>
	<view
		class="pure-waterfall-item"
		:class="_classes"
		:style="_styles"
		:hover-class="$attrs.hoverClass || $attrs['hover-class']"
	>
		<slot></slot>
	</view>
</template>

<script>
import commonComponentOptions from "../../config/common-component-options";
export default {
	options: commonComponentOptions,
};
</script>

<script setup>
import {
	ref,
	computed,
	onMounted,
	nextTick,
	getCurrentInstance,
	inject,
	watchEffect,
	onBeforeUnmount,
} from "vue";
import props from "./props";
import { getDOMRect } from "../../functions/dom";
import { generateUUID } from "../../functions/string";
import { sleep } from "../../functions/common";

// **************************************************************************************************************
// * Refs
// **************************************************************************************************************
// 向父组件添加子元素的函数
const AddPureWaterfallChildrenDOM = inject("AddPureWaterfallChildrenDOM");
// 删除父元素中的节点信息
const DeletePureWaterfallChildrenDOM = inject("DeletePureWaterfallChildrenDOM");
// 父元素计算出到布局信息
const PureWaterfallChildrenRects = inject("PureWaterfallChildrenRects");
// 列数
const PureWaterfallCols = inject("PureWaterfallCols");
// 间隔
const PureWaterfallGap = inject("PureWaterfallGap");
// 组件实例
const _instance = getCurrentInstance();
// uuid
const _uuid = generateUUID();
// 是否正在获取节点信息
let _isGettingRect = false;
// 等待更新节点信息的队列
let _waitingUpdateRect = [];

// **************************************************************************************************************
// * Options
// **************************************************************************************************************
defineOptions(commonComponentOptions);

// **************************************************************************************************************
// * Props
// **************************************************************************************************************
const _props = defineProps(props);

// **************************************************************************************************************
// * Emits
// **************************************************************************************************************
const _emits = defineEmits([]);

// **************************************************************************************************************
// * Classes
// **************************************************************************************************************
const _classes = computed(() => {
	const array = [];

	// uuid
	array.push(_uuid);

	// 是否已初始化
	if (_rect.value?.isInited) array.push("pure-waterfall-item--inited");

	// 是否更新位置
	if (_rect.value?.isUpdate) array.push("pure-waterfall-item--update");

	return array;
});

// **************************************************************************************************************
// * Styles
// **************************************************************************************************************
const _styles = computed(() => {
	const array = [];

	// top
	array.push(`top: ${_rect.value?.top || 0}px;`);

	// left
	array.push(
		`left: calc(var(--pure-waterfall-col-width) * ${
			_rect.value?.colIndex || 0
		} + var(--pure-waterfall-gap) * ${_rect.value?.colIndex || 0})`
	);

	// 加个delay效果
	// 随机0-50之间的整数
	array.push(
		`--pure-waterfall-animation-delay: ${Math.floor(
			Math.random() * 250
		)}ms;`
	);

	return array;
});

// **************************************************************************************************************
// * Watchers
// **************************************************************************************************************
watchEffect(() => {
	// 解构数组，不使用变量名，仅为触发依赖收集
	[
		_props.data,
		_props.index,
		_props.loaded,
		PureWaterfallCols.value,
		PureWaterfallGap.value,
	];

	// 更新节点信息
	_getRect();
});

// **************************************************************************************************************
// * Computed
// **************************************************************************************************************
// 计算出到当前元素的布局信息
const _rect = computed(() => {
	return PureWaterfallChildrenRects.value?.[_uuid];
});

// **************************************************************************************************************
// * 生命周期
// **************************************************************************************************************
onMounted(() => {
	//  获取节点信息
	_getRect();
});

onBeforeUnmount(() => {
	// 删除父元素中的节点信息
	DeletePureWaterfallChildrenDOM(_uuid);
});

// **************************************************************************************************************
// * Functions
// **************************************************************************************************************
// 获取节点信息
async function _getRect() {
	// 正在获取节点信息
	if (_isGettingRect) {
		// 将本地获取节点信息的任务添加到队列
		_waitingUpdateRect.push(1);
		return;
	}

	// 更新状态
	_isGettingRect = true;

	// 清空队列
	_waitingUpdateRect = [];

	// 等待数据渲染完成
	await nextTick();
	await sleep(100);

	// 获取节点信息
	await getDOMRect(`.${_uuid}`, _instance.proxy).then((data) => {
		// 将节点信息添加到父元素中
		AddPureWaterfallChildrenDOM({
			...data,
			uuid: _uuid,
			index: _props.index,
		});
	});

	// 继续计算
	// 等待一下，节省一点性能
	await sleep(100);

	// 更新状态
	_isGettingRect = false;

	// 如果队列不为空，则继续更新节点信息
	if (_waitingUpdateRect?.length > 0) _getRect();
}
</script>

<style scoped lang="scss">
@import "./style.scss";
</style>
